#ifndef PICCOLO_VK_GRAPHICS_CONTEXT_H
#define PICCOLO_VK_GRAPHICS_CONTEXT_H

#include "PiccoloGraphicsContext.h"
#include "PiccoloVKCommon.h"

namespace Piccolo
{
    struct QueueFamilyInfo
    {
        int32_t queueFamilyIndex = -1;
        uint32_t queueCount = 0;
    };

    class PiccoloVKGraphicsContext : public PiccoloGraphicsContext
    {
    public:
        PiccoloVKGraphicsContext(PiccoloWindow* window);
        ~PiccoloVKGraphicsContext() override;

        VkInstance GetInstance() const { return mInstance; }
        VkSurfaceKHR GetSurface() const { return mSurface; }
        VkPhysicalDevice GetPhysicalDevice() const { return mPhysicalDevice; }
        const QueueFamilyInfo& GetGraphicQueueFamilyInfo() const { return mGraphicQueueFamily; }
        const QueueFamilyInfo& GetPresentQueueFamilyInfo() const { return mPresentQueueFamily; }
        VkPhysicalDeviceMemoryProperties GetPhysicalDeviceMemoryProperties() const { return mPhysicalDeviceMemoryProperties; }
        bool IsSameGraphicPresentQueueFamily() const { return mGraphicQueueFamily.queueFamilyIndex == mPresentQueueFamily.queueFamilyIndex; }

    private:
        static void PrintPhysicalDeviceInfo(VkPhysicalDeviceProperties& props);
        static uint32_t GetPhysicalDeviceScore(VkPhysicalDeviceProperties& props);

        void CreateInstance();
        void CreateSurface(PiccoloWindow* window);
        void findPhysicalDevice();

        bool bShouldValidate = true;

        VkInstance mInstance;
        VkSurfaceKHR mSurface;

        VkPhysicalDevice mPhysicalDevice;

        QueueFamilyInfo mGraphicQueueFamily;
        QueueFamilyInfo mPresentQueueFamily;
        VkPhysicalDeviceMemoryProperties mPhysicalDeviceMemoryProperties;
    };
}

#endif